package com.spzx.user.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.spzx.common.core.constant.Constants;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.utils.MobileNumberValidator;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.user.service.SmsService;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.rmi.ServerException;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class SmsServiceImpl implements SmsService {
    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean sendCode(String phone) {
        // 1 手机号格式验证

        if (!MobileNumberValidator.isValidChineseMobileNumber(phone)) {
            throw new RuntimeException("该手机格式错误");
        }
        // 2 限制该手机号二分钟内只能发送一次
        if (stringRedisTemplate.hasKey(Constants.APP_LOGIN_LIMIT_PRIFIX + phone)) {
            throw new RuntimeException("请勿频繁获取验证码");
        }
        //3 限制该手机一天最多只能发送五次短信
        String countStr = stringRedisTemplate.opsForValue().get(Constants.APP_LOGIN_COUNT_PRIFIX + phone);
        if (!StringUtils.isEmpty(countStr) && Integer.parseInt(countStr) >= 5) {

            throw new RuntimeException("验证码发送异常");

        }
//发送短信

        try {
            String code = RandomUtil.randomNumbers(4);

            //短信发送成功
            //验证码缓存到redis:  过期时间20分钟
            stringRedisTemplate.opsForValue().set(Constants.APP_LOGIN_CODE_PRIFIX+phone,code,20, TimeUnit.MINUTES);
            //5、更新手机号获取验证码的频率次数
            //5.1 2分钟内不能重复获取验证码
            stringRedisTemplate.opsForValue().set(Constants.APP_LOGIN_LIMIT_PRIFIX+phone,"1",2,TimeUnit.MINUTES);
            if (stringRedisTemplate.opsForValue().increment(Constants.APP_LOGIN_LIMIT_PRIFIX+phone)==1L){
                stringRedisTemplate.expire(Constants.APP_LOGIN_COUNT_PRIFIX+phone,1,TimeUnit.DAYS);
            }
            return true;
        } catch (Exception _error) {
            throw new ServiceException(_error.getMessage());
        }
    }
}
